from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

import sys
import json
import webbrowser

from ui.mainFrom import Ui_mainForm
from Dev.paramconfig.Config import Config


class MWin(QWidget, Ui_mainForm):
    def __init__(self, parent=None):
        super(MWin, self).__init__(parent)
        self.setupUi(self)

        self.searchlineEdit.setPlaceholderText("输入查找内容")
        self.searchlineEdit.setToolTip("请输入查找内容")
        model = QStandardItemModel(0, 1, self)
        completer = QCompleter(model, self)
        completer.setMaxVisibleItems(7)
        completer.setFilterMode(Qt.MatchContains)
        self.searchlineEdit.setCompleter(completer)

        def textch(texts):
            strList = self.config.searchItem(texts, 1)
            if strList:
                model.removeRows(0, model.rowCount())
                for cn, i in enumerate(strList):
                    model.insertRow(0)
                    model.setData(model.index(0, 0), i)

        self.searchlineEdit.textChanged.connect(textch)

        # 获取列表
        self.config = None
        self.initFileMemu()
        self.ad = None
        self.pd = None

    def initFileMemu(self):
        # 获取列表
        self.urllist = self.readUrlList()
        if self.urllist != None:
            self.createWidgets()
            # # 添加事件处理
            self.doevent()
        else:
            self.error_handler('读取地址列表失败！请查看openlist.json文件是否存在并且格式正确。')

    def error_handler(self, emsg):
        print(emsg)
        QMessageBox.warning(self, "error_handler", emsg, QMessageBox.Ok)

    def readUrlList(self):
        try:
            self.config = Config()
            self.config.load()
            urllist = self.config.configs
            return urllist
        except FileNotFoundError:
            return None

    def doevent(self):
        # self.tabWidget.currentWidget().clicked.connect(self.dosolt)
        self.addButton.clicked.connect(self.additem)
        self.addButton.setShortcut("CTRL+N")
        self.delButton.clicked.connect(self.delitem)
        self.delButton.setShortcut("CTRL+D")

        self.searchlineEdit.returnPressed.connect(self.custonSlots)

    def custonSlots(self):
        print("custonSlots")
        print(self.searchlineEdit.text())
        rs = self.config.searchItem(self.searchlineEdit.text(), 2)
        print(rs)
        if rs is not None:
            self.tabWidget.setCurrentIndex(rs[0][0])
            # 选择单元格
            self.tabWidget.currentWidget().setCurrentCell(rs[0][2], rs[0][1])
            # 高亮单元格
            
        pass

    def dragEnterEvent(self, e):
        print(e)
        filename = e.mimeData().text()[8:]
        print(filename)
        e.accept()
        # self.addresslineEdit.setText(filename)

    def dropEvent(self, e):
        print(e)

    def createWidgets(self):
        # 加载地址列表
        # 添加tab
        for cn, tab in enumerate(self.urllist):
            # 设置
            createcols = 1
            createrows = 1

            newTableWidget = tableWidget(createrows, createcols)

            for linkitemcn, menu in enumerate(self.urllist[tab]):
                # print(self.urllist[tab][menu])

                currentColCount = newTableWidget.columnCount()
                if linkitemcn + 1 > currentColCount:
                    newTableWidget.setColumnCount(currentColCount + 1)

                for linkitemnamecn, linkitem in enumerate(self.urllist[tab][menu]):
                    # print(linkitem)

                    currentRowCount = newTableWidget.rowCount()
                    if linkitemnamecn+1 > currentRowCount:
                        newTableWidget.setRowCount(linkitemnamecn+1)

                    newTableWidget.setItem(linkitemnamecn, linkitemcn, QTableWidgetItem(linkitem))
                    # item 内容居中显示
                    newTableWidget.item(linkitemnamecn, linkitemcn).setTextAlignment(Qt.AlignHCenter|Qt.AlignVCenter)
            #
            # 允许拖拽
            # self.setAcceptDrops(True)

            # newTableWidget.setDragDropMode(QAbstractItemView.DragDropMode)
            # newTableWidget.setDragEnabled(True)
            # newTableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)
            # 禁止编辑操作
            newTableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
            newTableWidget.doubleClicked.connect(self.dosolt)
            newTableWidget.clicked.connect(self.doslotTranceNameToDelWidget)
            newTableWidget.setAcceptDrops(True)

            # 依据二级的标题创建 Git 目录 文件  软件 等文件列信息
            newTableWidget.setHorizontalHeaderLabels(self.urllist[tab])
            newTableWidget.verticalHeader().setVisible(False)
            newTableWidget.horizontalHeader().setStyleSheet("QHeaderView::section{border: none; background: rgba(15, 135, 208, 100);}")
            self.tabWidget.addTab(newTableWidget, tab)



    def saveUrllist(self):
        self.config.configs = self.urllist
        self.config.save()
        # with open('openlist.json', 'w', encoding='utf-8') as f:
        #     json.dump(self.urllist, f, ensure_ascii=False, indent=4)
        #
        print('文件保存成功。')

    def dosolt(self, QModelIndex):
        print("do clicked slot", QModelIndex.row(), QModelIndex.column())
        try:
            menu_str = self.tabWidget.currentWidget().horizontalHeaderItem(QModelIndex.column()).text()
            if menu_str is None:
                return
            print(menu_str)
            key_str = self.tabWidget.currentWidget().currentItem().text()
            if key_str is None:
                return
            print(key_str)
            # 执行webserch功能
            tab_str = self.tabWidget.tabText(self.tabWidget.currentIndex())
            self.openlink(tab_str, menu_str, key_str)

        except Exception as e:
            print("openlink:" + str(e))
            QMessageBox.warning(self, "openlink",  str(e), QMessageBox.Ok)

    def doslotTranceNameToDelWidget(self, QModelIndex):
        print("do signal clicked slot", QModelIndex.row(), QModelIndex.column())
        if self.pd is not None or self.ad is not None:
            try:
                # 执行webserch功能
                tab_str = self.tabWidget.tabText(self.tabWidget.currentIndex())

                menu_str = self.tabWidget.currentWidget().horizontalHeaderItem(QModelIndex.column()).text()
                key_str = ""
                value_str = ""
                try:
                    key_str = self.tabWidget.currentWidget().currentItem().text()
                    value_str = self.config.configs[tab_str][menu_str][key_str]
                except Exception as e:
                    print(e)


                if self.pd is not None:
                    self.pd.pageComboBox.setCurrentText(tab_str)
                    self.pd.colComboBox.setCurrentText(menu_str)
                    self.pd.namelineEdit.setText(key_str)
                    self.pd.addresslineEdit.setText(value_str)

                if self.ad is not None:
                    self.ad.pageComboBox.setCurrentText(tab_str)
                    self.ad.colComboBox.setCurrentText(menu_str)
                    self.ad.namelineEdit.setText(key_str)
                    self.ad.addresslineEdit.setText(value_str)


            except Exception as e:
                print("openlink:" + str(e))
                QMessageBox.warning(self, "openlink",  str(e), QMessageBox.Ok)




    def cleanWidgets(self):
        try:
            if self.tabWidget.currentWidget() is not None:
                self.tabWidget.currentWidget().clear()
                self.tabWidget.clear()
            else:
                print("currentWidget is empty")
        except Exception as e:
            print("cleanWidgets:"+e)


    def additem(self):
        try:
            # self.cleanWidgets()
            print(" additem(self) ")
            if self.ad is None:
                self.ad = PopupDialog(self)

            if self.ad is not None:
                self.ad.show()
            # pw.Signal_OneParameter.connect(self.custonSlots)
        except Exception as e:
            self.error_handler(str(e))


    def delitem(self):
        try:
            # self.cleanWidgets()
            print(" delitem(self) ")
            if self.pd is None:
                self.pd = DelDialog(self)
            if self.pd is not None:
                self.pd.show()
        except Exception as e:
            self.error_handler(str(e))

    def openurl(self, url):
        if url is not None and url != '':
            webbrowser.open(url)
        else:
            self.error_handler('打开地址失败！地址为空。')

    # TAB 行 列 --> json obj -->value(url)
    def getURL(self, tabname, col_str, key_str):
        # 处理数据的对象self.urllist json
        url = self.urllist[tabname][col_str][key_str]
        print(url)
        return url

    def openlink(self, tabname, col_str, key_str):
        url = self.getURL(tabname, col_str, key_str)
        self.openurl(url)


class tableWidget(QTableWidget):
    def __init__(self, *__args):
        super().__init__(*__args)
        # 表格头随控件变化(水平方向占满窗体)
        # self.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        # self.verticalHeader().setSectionResizeMode(QHeaderView.Stretch) # 行自适应宽度
        # self.customContextMenuRequested.connect(self.generateMenu)
        # self.setAcceptDrops(True)

    def generateMenu(self, pos):
        print(pos)
        # 判断当前选中的位置
        for i in self.selectionModel().selection().indexes():
            rowNum = i.row()
            colNum = i.column()
        # 弹出位置
        menu = QMenu()
        item1 = menu.addAction("添加")
        item2 = menu.addAction("删除")
        item3 = menu.addAction("修改")
        pos2 = QPoint()
        pos2.setX(pos.x())
        pos2.setY(pos.y() + 30)
        screenPos = self.mapToGlobal(pos2)
        # 被阻塞
        action = menu.exec_(screenPos)
        try:
            if action == item1:
                if self.item(rowNum, colNum) is None:
                    linkname = "11"
                    self.setItem(rowNum, colNum, QTableWidgetItem(linkname))
                elif self.item(rowNum, colNum).text() == " ":
                    linkname = "11"
                    self.setItem(rowNum, colNum, QTableWidgetItem(linkname))

                print("选择了第一个菜单项", self.item(rowNum, colNum).text())
            elif action == item2:
                if self.item(rowNum, colNum) is not None:
                    print("设置为空")
                    self.item(rowNum, colNum).setText(" ")

                print("选择了第二个菜单项", self.item(rowNum, colNum).text())

            else:
                print("选择了第三个菜单项", self.item(rowNum, colNum).text())
                if self.item(rowNum, colNum) is not None:
                    self.item(rowNum, colNum).setText("11")
        except Exception as e:
            print(str(e))

    def dragEnterEvent(self, e):
        print(e)
        filename = e.mimeData().text()[8:]
        print(filename)
        e.accept()
        try:
            for i in self.selectionModel().selection().indexes():
                rowNum = i.row()
                colNum = i.column()

            print(rowNum, colNum)
            self.setItem(rowNum, colNum, QTableWidgetItem(filename.split('/')[-1]))
            # 只做pythonJson数据结构对象的更新
            # upDataJsonFile()
        except Exception as e:
            print(str(e))

    def dropEvent(self, e):
        filename = e.mimeData().text()[8:]
        print(filename)
        self.currentItem().setText(filename)


from ui.DelDialog import Ui_DelDialog
class DelDialog(QDialog, Ui_DelDialog):
    def __init__(self, parent=None):
        super(DelDialog, self).__init__(parent)
        self.setupUi(self)
        self.parent = parent
        self.initUI()
        self.initSignalSlots()


    def initUI(self):
        self.pageComboBox.clear()
        self.colComboBox.clear()

        if self.parent.urllist:
            self.pagelist = list(self.parent.urllist)
            self.currentcollist = self.parent.urllist[self.pagelist[0]]
            self.pageComboBox.addItems(self.pagelist)
            self.colComboBox.addItems(self.currentcollist)

            print(list(self.pagelist))
            print(list(self.currentcollist))
        else:
            print("current list empt")
            raise IOError("current list empt")

    def initSignalSlots(self):
        self.okButton.clicked.connect(self.doOKSlot)
        self.pageComboBox.currentIndexChanged.connect(self.doslotsPageComboBoxChange)
        self.cancelButton.clicked.connect(self.close)

    def doslotsPageComboBoxChange(self, strSN):
        try:
            print(strSN)
            strvalue = self.pageComboBox.itemText(strSN)
            print(strvalue)
            self.currentcollist = self.parent.urllist[strvalue]
            self.colComboBox.clear()
            self.colComboBox.addItems(self.currentcollist)
        except Exception as e:
            print(e)

    def doOKSlot(self):
        # 方法一：可以将json文件修改让界面刷新
        # 方法二：配置给ui ui修改界面 然后更新到文件
        # self.Signal_OneParameter.emit(1)

        tabname = self.pageComboBox.currentText()
        Menuname = self.colComboBox.currentText()
        urlname = self.namelineEdit.text().strip()
        url = self.addresslineEdit.text().strip()

        if tabname == '':
            QMessageBox.warning(self, "error",  "tab不能为空", QMessageBox.Ok)
            return

        try:
            # 在当前步骤必须满足 tab menu line value 全部都不为空
            # 当当前的tab 为新的时候
            if self.needDelSelfCheckBox.isChecked():
                self.parent.urllist.pop(tabname)
            elif urlname != '':
                self.parent.urllist[tabname][Menuname].pop(urlname)
            elif Menuname != '':
                if self.parent.urllist[tabname].get(Menuname):
                    self.parent.urllist[tabname][Menuname].clear()
            elif tabname != '':
                if self.parent.urllist.get(tabname):
                    self.parent.urllist[tabname].clear()

            self.parent.cleanWidgets()
            # 保存到本地json
            self.parent.saveUrllist()
            self.parent.createWidgets()
            # self.parent.tabWidget.setCurrentIndex(self.pageComboBox.currentIndex())
            self.initUI()

        except Exception as e:
            print(e)


from ui.PopupDialog import Ui_PopupDialog
# 添加子item的界面
class PopupDialog(QDialog, Ui_PopupDialog):
    # 声明带一个int类型参数的信号
    Signal_OneParameter = pyqtSignal(int)

    def __init__(self, parent=None):
        super(PopupDialog, self).__init__(parent)
        self.setupUi(self)
        # 允许拖拽放置
        self.setAcceptDrops(True)
        self.parent = parent
        self.initUI()
        self.initSignalSlots()

    def initUI(self):
        if self.parent.urllist:
            self.pagelist = list(self.parent.urllist)
            self.currentcollist = self.parent.urllist[self.pagelist[0]]
            self.pageComboBox.addItems(self.pagelist)
            self.colComboBox.addItems(self.currentcollist)

            print(list(self.pagelist))
            print(list(self.currentcollist))
        else:
            print("current Json is empt")

    def initSignalSlots(self):
        self.okButton.clicked.connect(self.doOKSlot)
        self.pageComboBox.currentIndexChanged.connect(self.doslotsPageComboBoxChange)
        self.cancelButton.clicked.connect(self.close)

    def doslotsPageComboBoxChange(self, strSN):
        try:
            print(strSN)
            strvalue = self.pageComboBox.itemText(strSN)
            print(strvalue)
            self.currentcollist = self.parent.urllist[strvalue]
            self.colComboBox.clear()
            self.colComboBox.addItems(self.currentcollist)
        except Exception as e:
            print(e)

    def setValue_OneParameter(self, nIndex):
        '''带一个参数(整数)的槽函数'''
        print("setValue_OneParameter:", nIndex)
        pass

    def dragEnterEvent(self, e):
        print(e)
        filename = e.mimeData().text()[8:]
        print(filename)
        e.accept()
        self.namelineEdit.setText(filename.split('/')[-1])
        self.addresslineEdit.setText(filename)

    def dropEvent(self, e):
        print(e)

    def doOKSlot(self):
        # 方法一：可以将json文件修改让界面刷新
        # 方法二：配置给ui ui修改界面 然后更新到文件
        self.Signal_OneParameter.emit(1)

        urlname = self.namelineEdit.text().strip()
        url = self.addresslineEdit.text().strip()
        tabname = self.pageComboBox.currentText()
        Menuname = self.colComboBox.currentText()

        if urlname == '' or url == '' or tabname == '' or Menuname == '':
            QMessageBox.warning(self, "警告", '输入不能为空！', QMessageBox.Ok)
            return

        if urlname in self.parent.urllist:
            if QMessageBox.information(self, '提示', '名称 ‘%s’ 已存在，将会覆盖，是否继续？' % urlname, QMessageBox.Ok | QMessageBox.No):
                pass
            else:
                return

        tabobj = {urlname: url}
        # 在当前步骤必须满足 tab menu line value 全部都不为空
        # 当当前的tab 为新的时候
        if self.parent.urllist.get(tabname) is None:
            dict = {tabname: {Menuname: tabobj}}
            self.parent.urllist.update(dict)
        elif self.parent.urllist[tabname].get(Menuname) is None:
            dict = {Menuname: tabobj}
            self.parent.urllist[tabname].update(dict)
        elif self.parent.urllist[tabname][Menuname].get(urlname) is None:
            dict = tabobj
            self.parent.urllist[tabname][Menuname].update(dict)
        else: # 更新item的值
            self.parent.urllist[tabname][Menuname][urlname] = url

        try:
            self.parent.cleanWidgets()
            # 保存到本地json
            self.parent.saveUrllist()
            self.parent.createWidgets()

            index = self.pageComboBox.currentIndex()
            tablsit = list(self.parent.urllist)
            for cn, itr in enumerate(tablsit):
                if itr == tabname:
                    index = cn
            self.parent.tabWidget.setCurrentIndex(index)
        except Exception as e:
            print(e)

        # self.destroy()  # 銷燬窗口

    


if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MWin()
    try:
        qssfile = open("./qss/style.qss", encoding='utf-8')
        qssStyle = qssfile.read()
        qssfile.close()
        w.setStyleSheet(qssStyle)
    except Exception as e:
        print(e)
    w.show()
    sys.exit(app.exec_())

